\insert 'List.oz'

declare

fun {ApplyMoves S Ms}
   case Ms of nil then [S]
   [] M|Mr then
      S1 = case M of trackA(N) then
         if N>0 then
       NewO = {Append
          {Drop S.main {Length S.main}-N}
          S.trackA}
       NewM = {Take S.main {Length S.main}-N} in
       state(main:NewM trackA:NewO trackB:S.trackB)
         elseif N<0 then
       NewM = {Append
          S.main
          {Take S.trackA ~N}}
       NewO = {Drop S.trackA ~N} in
       state(main:NewM trackA:NewO trackB:S.trackB)
         else S end
      [] trackB(N) then
         if N>0 then
       NewT = {Append
          {Drop S.main {Length S.main}-N}
          S.trackB}
       NewM = {Take S.main {Length S.main}-N} in
       state(main:NewM trackA:S.trackA trackB:NewT )
         elseif N<0 then
       NewM = {Append
          S.main
          {Take S.trackB ~N}}
       NewT = {Drop S.trackB ~N} in
       state(main:NewM trackA:S.trackA trackB:NewT)
         else
       S
         end
      end
   in
      S | {ApplyMoves S1 Mr}
   end
end
